#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/cpu.h>
#include <linux/sched.h>
#include <linux/sched/task.h>
#include <linux/sched/init.h>
#include <linux/hrtimer.h>
#include <linux/irqflags.h>
#include <linux/percpu.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/workqueue.h>
#include <linux/sched/task_stack.h>

char boot_command_line[32];

static void __noreturn rest_init(void)
{
    extern void kernel_init_startup(void);

    kernel_init_startup();

    kthread_daemon_startup();

    /*
     * The boot idle thread must execute schedule()
     * at least once to get things moving:
     */
    schedule_preempt_disabled();

    /* Call into cpu_idle with preempt disabled */
    cpu_startup_entry(CPUHP_ONLINE);
}

__weak void init_task_struct_setup_extra(void)
{
    /* Initialize task::filedesc etc */
}

__weak void smp_setup_processor_id(void)
{
}

void start_kernel(void)
{
    set_task_stack_end_magic(&init_task);

    smp_setup_processor_id();

    local_irq_disable();

    setup_arch(0);

    call_early_init();
    boot_cpu_init();
    setup_per_cpu_areas();

    boot_cpu_hotplug_init();

    mm_core_init();

    sched_init();

	/*
	 * Allow workqueue creation and work item queueing/cancelling
	 * early.  Work item execution depends on kthreads and starts after
	 * workqueue_init().
	 */
	workqueue_init_early();

    init_task_struct_setup_extra();

    init_IRQ();
    init_timers();

    hrtimers_init();
    timekeeping_init();
    time_init();

    rest_init();
}
